#include <types.h>
#include <stdlib.h>
#include <stdio.h>

#define IDTLIMIT 0x22
extern void vector0();
extern void vector1();
extern void vector2();
extern void vector3();
extern void vector4();
extern void vector5();
extern void vector6();
extern void vector7();
extern void vector8();
extern void vector9();
extern void vector10();
extern void vector11();
extern void vector12();
extern void vector13();
extern void vector14();
extern void vector15();
extern void vector16();
extern void vector17();
extern void vector18();
extern void vector19();
extern void vector_reserved();
extern void vector32();
extern void vector33();





struct _idt_entry
{
  uint_16 offset_0_15;
  uint_16 selector __attribute__((packed)) ;
  uint_8  reserved __attribute__((packed)) ;
  uint_8  flag __attribute__((packed)) ;
  uint_16 offset_16_31 __attribute__((packed)) ;
}idt[IDTLIMIT + 1];






void init_idt_entry(int n, void fun())
{
    idt[n].offset_0_15 = (uint_32)fun & 0xffff;
    idt[n].offset_16_31= (uint_32)fun >> 16;
    idt[n].reserved = 0;
    idt[n].flag = 0x8e;
    idt[n].selector = 0x20;
}



void load_idtr(struct _idt_entry *idt)
{
  struct _idtr
  {
    uint_16 limit;
    uint_32 base;
  }   __attribute__((packed)) idtr;
  

  idtr.limit = IDTLIMIT * 8;
  idtr.base = (uint_32)idt ;
  
  asm("lidt %w0"
      ::"m"(idtr)
      );

}


void init_idt_table()
{
  init_idt_entry(0, vector0);
  init_idt_entry(1, vector1);
  init_idt_entry(2, vector2);
  init_idt_entry(3, vector3);
  init_idt_entry(4, vector4);
  init_idt_entry(5, vector5);
  init_idt_entry(6, vector6);
  init_idt_entry(7, vector7);
  init_idt_entry(8, vector8);
  init_idt_entry(9, vector9);
  init_idt_entry(10, vector10);
  init_idt_entry(11, vector11);
  init_idt_entry(12, vector12);
  init_idt_entry(13, vector13);
  init_idt_entry(14, vector14);
  init_idt_entry(15, vector15);
  init_idt_entry(16, vector16);
  init_idt_entry(17, vector17);
  init_idt_entry(18, vector18);
  init_idt_entry(19, vector19);
  init_idt_entry(20, vector_reserved);
  init_idt_entry(21, vector_reserved);
  init_idt_entry(22, vector_reserved);
  init_idt_entry(23, vector_reserved);
  init_idt_entry(24, vector_reserved);
  init_idt_entry(25, vector_reserved);
  init_idt_entry(26, vector_reserved);
  init_idt_entry(27, vector_reserved);
  init_idt_entry(28, vector_reserved);
  init_idt_entry(29, vector_reserved);
  init_idt_entry(30, vector_reserved);
  init_idt_entry(31, vector_reserved);
  init_idt_entry(32, vector32);
  init_idt_entry(33, vector33);
  
}

  
  

void init_interrupt()
{
  printf("Init interrupt system\n");
  init_idt_table();
  load_idtr(idt);
  
}
